﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

using YLPublicService.TransferModel;
using YLClient.YLServiceClient;
using YLClient.Config;

namespace YLClient.Util
{
    //delegate void BeforeTransferNextEventHandler(string fileName, int index, int count);
    //delegate void OnTransferFileErrorEventHandler(string fileName, int index);
    /// <summary>
    /// 执行下一次传输时被触发
    /// </summary>
    /// <param name="preFileName"></param>
    /// <param name="precent">当前工作进度</param>
    delegate void TransfefMoveNext(string preFileName, double precent);
    delegate void TransferFileError(string fileName);

    internal class ClientAdapter
    {
        ServiceClient svcClient;
        FTP ftp;
        FtpServerInfo info;
        public ClientAdapter(bool regetFtpServerInfo)
        {
            svcClient = ServiceClient.GetServiceClient();
            info = svcClient.RequestFtpServerInfo(regetFtpServerInfo);
            ftp = new FTP(info.IPV4, info.ClientLoginName, info.ClientPassWord);
        }

        //public event BeforeTransferNextEventHandler BeforeTransferNext;
        //public event OnTransferFileErrorEventHandler OnTransferFileError;
        /// <summary>
        /// 提供并行模型使用
        /// </summary>
        public event TransfefMoveNext OnTransfefMoveNext;
        /// <summary>
        /// 提供并行模型使用
        /// </summary>
        public event TransferFileError OnTransferError;
        ///bool参数是 代表是否有错
        public event Action<bool> OnTransferFinish;

        //当前工作进度
        int currentValue;
        //完成工作时的进度
        int finalValue;
        /// <summary>
        /// 往数据库以及ftp服务器上传数据
        /// </summary>
        /// <param name="workItem"></param>
        /// <param name="uploadFiles"></param>
        //public bool AddWorkItem(WorkItem workItem, string[] uploadFiles)
        //{
        //    if (svcClient.AddWorkItem(workItem, GlobalClass.DataContainer.Guid))
        //    {
        //        bool hasErr = false;
        //        ftp.Connect();

        //        for (int i = 0; i < uploadFiles.Length; i++)
        //        {
        //            var containErr = uploadFile(workItem, uploadFiles[i], i, uploadFiles.Length);
        //            if (containErr)
        //                hasErr = true;
        //        }

        //        ftp.Close();
        //        if (!hasErr)
        //        {
        //            svcClient.UpdatedWorkItemStatus(workItem, WorkItemStatus.WaitingProcess, guid);
        //            return true;
        //        }
        //    }
        //    return false;
        //}

        private List<Tuple<WorkItem, string>> errorUploadWorkItems;

        /// <summary>
        /// 只负责上传文件
        /// 并行添加文件.并行功能暂无法实现。底层ftp对象不支持，多线程调用发送文件方法。
        /// </summary>
        /// <param name="workItem"></param>
        /// <param name="uploadFiles"></param>
        /// <param name="present">表示多少工作完成时触发提示进度事件</param>
        /// <returns></returns>
        public bool UploadWorkItemFiles(WorkItem workItem, string[] uploadFiles, double present)
        {
            bool hasErr = false;
            ftp.Connect();
            currentValue = 0;
            finalValue = uploadFiles.Count();
            var remoteDir = ClientConfig.GetRemoteSaveDir(workItem);
            foreach (var file in uploadFiles)
            {
                var containErr = uploadFile(remoteDir, file);
                if (OnTransfefMoveNext != null && (currentValue * 1.0 / finalValue >= present))
                {
                    OnTransfefMoveNext(file, currentValue * 100.0 / finalValue);
                    present += present;
                }
                if (containErr)
                    hasErr = true;
            }
            ftp.Close();

            return hasErr == false;
        }
        /// <summary>
        /// 添加单个文件到ftp服务器，返回bool代表成功失败
        /// </summary>
        /// <param name="workItem"></param>
        /// <param name="file"></param>
        /// <param name="index"></param>
        /// <param name="count">文件总数</param>
        /// <returns></returns>
        //private bool uploadFile(WorkItem workItem, string file, int index, int count)
        //{
        //    bool hasErr = false;
        //    string remoteDirname = workItem.boyName + "&" + workItem.grilName + "\\" + workItem.TemplateName + "\\";
        //    if (BeforeTransferNext != null)
        //    {
        //        BeforeTransferNext(file, index, count);
        //    }
        //    var fileName = Common.getFileName(file);
        //    try
        //    {
        //        ftp.UploadFile(remoteDirname + fileName, file);
        //    }
        //    catch
        //    {
        //        hasErr = true;
        //        if (OnTransferFileError != null) //判断客户代码是否挂钩错误处理过程
        //        {
        //            OnTransferFileError(file, index);
        //        }
        //        else
        //        {
        //            throw;//如果客户代码没有编写错误处理过程，就抛出异常
        //        }
        //    }
        //    if (OnTransferFinish != null)
        //    {
        //        OnTransferFinish(hasErr);
        //    }
        //    return hasErr;
        //}
        private bool uploadFile(string remoteDir, string file)
        {
            bool hasErr = false;
            var fileName = Common.getFileName(file);
            try
            {
                ftp.UploadFile(Common.conbindPath(remoteDir, fileName), file);
                currentValue++;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                hasErr = true;
                if (OnTransferError != null) //判断客户代码是否挂钩错误处理过程
                {
                    OnTransferError(file);
                }
                else
                {
                    throw;//如果客户代码没有编写错误处理过程，就抛出异常
                }
            }

            if (OnTransferFinish != null)
            {
                OnTransferFinish(hasErr);
            }
            return hasErr;
        }
        public bool DownloadFile(WorkItem workItem, string localDir)
        {
            var client = ServiceClient.GetServiceClient();
            var filepath = client.GetFinishFileServerPath(workItem.WorkItemID);

            ftp.DownloadFile(filepath, Common.conbindPath(localDir, Common.getFileName(filepath)));
            return true;
        }
    }
}
